﻿using Styx;

using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;

using CommonBehaviors.Actions;
using Styx.Common;
using Styx.CommonBot;

using System.Linq;
using System.Collections.Generic;

namespace Crusader
{
    partial class Routine: CombatRoutine
    {

        public partial class Paladin
        {

            public enum Seal
            {
                None = 0,
                SoT,
                SoR,
                SoL,
                Auto
            }

            public enum Blessings
            {
                None,
                Kings,
                Might
            }

            #region Combat buff composites

            public static Composite CombatBuffBehavior()
            {
                
                return new PrioritySelector(
                    //Seal Time!
                    //CastBuff("Seal of Truth", ret => Crusader.Settings.Instance.Paladin_Seal == Seal.SoT && !PlayerHasBuff("Seal of Truth") || Crusader.Settings.Instance.Paladin_Seal == Seal.Auto && !PlayerHasBuff("Seal of Truth") && (EnemyUnits.Count < Crusader.Settings.Instance.AoEAt)),
                    //CastBuff("Seal of Righteousness", ret => Crusader.Settings.Instance.Paladin_Seal == Seal.SoR && !PlayerHasBuff("Seal of Righteousness") || Crusader.Settings.Instance.Paladin_Seal == Seal.Auto && !PlayerHasBuff("Seal of Righteousness") && EnemyUnits.Count >= Crusader.Settings.Instance.AoEAt),
                    //CastBuff("Seal of Light", ret => Crusader.Settings.Instance.Paladin_Seal == Seal.SoL && !PlayerHasBuff("Seal of Light")),

                    //Blessings
                    new Decorator(ret => Crusader.Settings.Instance.RaidBuffs == Settings.AllowBuff.Enabled || (Crusader.Settings.Instance.RaidBuffs == Settings.AllowBuff.WellFed && (PlayerHasBuff("Well Fed") || Me.Combat)),
                        new PrioritySelector(
                            CastBuff("Blessing of Kings", ret => Crusader.Settings.Instance.Paladin_Blessings == Blessings.Kings && (!PlayerHasBuff("Blessing of Kings") && !PlayerHasBuff("Mark of the Wild"))),
                            CastBuff("Blessing of Might", ret => Crusader.Settings.Instance.Paladin_Blessings == Blessings.Might && !PlayerHasBuff("Blessing of Might"))
                        )
                    )
                );
            }

            #endregion

            #region Pre-combat buff composites

            public static Composite PreCombatBuffBehavior()
            {
                return CombatBuffBehavior();
            }

            #endregion


            private static WoWUnit LastDJTarget = null;
            public static Composite DoubleJeopardy()
            {

                WoWUnit target = null;
                return new Decorator(ret => CanCastSpell("Judgment") && PlayerHasBuff("Glyph of Double Jeopardy"),
                    new Action( delegate{
                        //if (Me.CurrentTarget != null && Me.CurrentTarget.Equals(LastDJTarget))
                        //{
                            foreach (WoWUnit u in NearbyUnfriendlyUnits)
                            {
                                if (u.Guid != LastDJTarget.Guid

                                    && u.Distance <= 30.0
                                    && !Crusader.Routine.IsCrowdControlled(u)
                                    && (target == null || u.Distance < target.Distance))
                                {
                                    target = u;
                                }
                            }
                            if (target != null && target.Guid != LastDJTarget.Guid)
                            {
                                if (SpellManager.Cast("Judgment", target))
                                {

                                    Logging.Write("[{0}] Double Jeopardy (Judgment) @{1}", CurrentHolyPower(), target.Guid);
                                    LastDJTarget = target;

                                }
                                return RunStatus.Success;
                            }
                        //    
                        //}
                        return RunStatus.Failure;
                    }
                ));
            }

            public static Composite CastJudgment()
            {
                string SpellName = "Judgment";
                return new Decorator(ret => CanCastSpell(SpellName),
                    new Action(delegate
                    {
                        if (Crusader.Settings.Instance.Paladin_Ret_JudgmentBonus
                            && PlayerHasBuff("Glyph of Double Jeopardy"))
                            return RunStatus.Failure;

                        if (SpellManager.Cast(SpellName))
                        {
                            LastDJTarget = Me.CurrentTarget;
                            Logging.Write("[{0}] {1}", CurrentHolyPower(), SpellName);
                            return RunStatus.Success;
                            
                        }
                        return RunStatus.Failure;
                    })
               );
            }

            public static Composite AoETargeting()
            {

                return new Decorator(ret => Crusader.Settings.Instance.AllowTargeting,
                    new Action(delegate
                    {
                        IEnumerable<WoWUnit> unitsInFrontOfMeMelee = NearbyUnitsInCombatWithMe.Where(u => (u.Distance <=5 || u.IsWithinMeleeRange) && u.InLineOfSight && u.InLineOfSpellSight && Me.IsSafelyFacing(u)).OrderBy(u => u.Distance);

                        WoWUnit bestTarget = null;

                        if (Me.HasAura("Seal of Truth"))
                        {
                            foreach (WoWUnit u in unitsInFrontOfMeMelee)
                            {
                                IEnumerable<WoWAura> auras = u.GetAllAuras().Where(a => a.Name.Equals("Censure") && a.CreatorGuid == Me.Guid);

                                WoWAura bestAura = null;

                                if (auras.Count() > 0 && bestTarget != null)
                                {
                                    WoWAura cen = auras.First();

                                    if ((cen.TimeLeft.Seconds < 5 || cen.StackCount < 5) && (bestAura != null && ( cen.TimeLeft < bestAura.TimeLeft|| cen.StackCount < bestAura.StackCount)))
                                    {
                                        bestTarget = u;
                                        bestAura = cen;
                                    }
                                }
                                else
                                {
                                    bestTarget = u;
                                    if (auras.Count() > 0)
                                        bestAura = auras.First();
                                }
                            }
                        }
                        else
                        {
                            bestTarget = unitsInFrontOfMeMelee.First();
                        }

                        if(bestTarget!=null)
                            bestTarget.Target();

                        return RunStatus.Failure;
                    })
                );
            }

            public static Composite CastHammerOfWrath()
            {
                string SpellName = "Hammer of Wrath";
                return new Decorator(ret => CanCastSpell(SpellName),
                    new Action(delegate
                    {
                        IEnumerable<WoWUnit> sub20 = NearbyUnitsInCombatWithMe.Where(u => u.HealthPercent <= 20 && u.Distance <= 30 && u.InLineOfSight && u.InLineOfSpellSight && Me.IsSafelyFacing(u));

                        if (sub20.Count() < 1)
                            return RunStatus.Failure;

                        foreach (WoWUnit u in sub20)
                        {
                            try
                            {
                                if (u.IsValid && SpellManager.Cast(SpellName, u))
                                {
                                    Logging.Write("[{0}] {1}", CurrentHolyPower(), SpellName);
                                    return RunStatus.Success;

                                }
                            }
                            catch { }
                        }
                        return RunStatus.Failure;
                    })
               );
            }
        }
    }
}